package com.kongyz.registry;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @author kongyz
 * @date 2018/8/6 22:43
 * @Description: 服务注册
 */
public class ServiceRegistry {

    private final Logger logger=LoggerFactory.getLogger(this.getClass());
    /**
     * 类似计数器的一个功能
     * 能够使一个线程在等待另外一些线程完成各自工作之后，再继续执行
     */
    private CountDownLatch latch=new CountDownLatch(1);

    private String registryAddress;

    public ServiceRegistry(String registryAddress) {
        this.registryAddress = registryAddress;
    }

    /**
     * 注册服务
     * @param data
     */
    public void register(String data){
        if(data!=null){
            ZooKeeper zk=connectServer();
            if(zk!=null){
                addrootNode(zk);
                createNode(zk,data);
            }
        }
    }

    /**
     * 创建连接
     * @return
     */
    private ZooKeeper connectServer(){
        ZooKeeper zk=null;
        try {
            zk=new ZooKeeper(registryAddress, Constant.ZK_SESSION_TIMEOUT, new Watcher() {
                public void process(WatchedEvent watchedEvent) {
                    if(watchedEvent.getState()==Event.KeeperState.SyncConnected){
                        latch.countDown();
                    }
                }
            });
            latch.await();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return zk;
    }

    /**
     * 添加跟节点目录
     * @param zk
     */
    private void addrootNode(ZooKeeper zk){
        try {
            Stat s=zk.exists(Constant.ZK_REGISTRY_PATH,false);
            if(s==null){
                zk.create(Constant.ZK_REGISTRY_PATH,new byte[0],ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建数据节点，
     * 此节点为临时节点，session结束后将消失，
     * 此节点带节点序号，序号由zk父节点来维护
     * @param zk
     * @param data
     */
    private void createNode(ZooKeeper zk,String data){
        try {
            byte[] bytes=data.getBytes();
            String path=zk.create(Constant.ZK_DATA_PATH,bytes,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
            logger.debug("zookeeper 创建节点：({}=>{})",path,data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }







}
